/*!
 * \file frreport_comm.h
 *
 * \brief report_comm公用
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.\n
 * report公用函数
 *
 * \version 2.0
 * \author yaohl
 * \date 2014/12/23
 *
 */

#ifndef __FRREPORT_COMM_H_
#define __FRREPORT_COMM_H_

#include "frcomm.h"
#include "frlist.h"
#include "frhash2.h"
#include "frsutl.h"

#include "conntrack.h"
#include "module.h"

//保存l7data的链表
#define APM_REPORT_TYPE_L7DATA     0   //l7data数据链表
#define APM_REPORT_TYPE_OTHER      1   //其他上报数据

//通用指标项名称
#define APM_REPORT_KEY_SESSION                  "session"
#define APM_REPORT_KEY_SESSION_ID               APM_REPORT_KEY_SESSION ".id"
#define APM_REPORT_KEY_SESSION_USERNAME         APM_REPORT_KEY_SESSION ".username"           // 登录的用户名
#define APM_REPORT_KEY_SESSION_LOGIN_TIMESTAMP  APM_REPORT_KEY_SESSION ".login_timestamp"    // 登录成功的时间戳(单位毫秒)
#define APM_REPORT_KEY_SESSION_SERVER           APM_REPORT_KEY_SESSION ".server"             // 服务名，包括版本号

#define APM_REPORT_KEY_TRANS                    "transaction"
#define APM_REPORT_KEY_TRANS_TITLE              APM_REPORT_KEY_TRANS ".title"                // URL/SQL
#define APM_REPORT_KEY_TRANS_CODE               APM_REPORT_KEY_TRANS ".code"                 // 交易跟踪码
#define APM_REPORT_KEY_TRANS_RELATED_ID         APM_REPORT_KEY_TRANS ".related_id"           // 关联ID号

#define APM_REPORT_KEY_CONN                     "connection"
#define APM_REPORT_KEY_CONN_ID                  APM_REPORT_KEY_CONN ".id"
#define APM_REPORT_KEY_CONN_EST_TIMESTAMP       APM_REPORT_KEY_CONN ".establish_timestamp"   // 建立时间戳
#define APM_REPORT_KEY_CONN_SYN_TIME_US         APM_REPORT_KEY_CONN ".syn_time_us"           // 建链时间

#define APM_REPORT_KEY_REQ                      "request"
#define APM_REPORT_KEY_REQ_ID                   APM_REPORT_KEY_REQ".id"
#define APM_REPORT_KEY_REQ_ISRESPREQUIRED       APM_REPORT_KEY_REQ".isResponseRequired"      // 是否期待回应
#define APM_REPORT_KEY_REQ_START_TIMESTAMP      APM_REPORT_KEY_REQ".start_time"              // 请求发起时间
#define APM_REPORT_KEY_REQ_END_TIMESTAMP        APM_REPORT_KEY_REQ".end_time"                // 请求结束时间
#define APM_REPORT_KEY_REQ_SEND_TIME_US         APM_REPORT_KEY_REQ".send_time_us"            // 请求发送时间(单位usec)
#define APM_REPORT_KEY_REQ_DATA_BYTES           APM_REPORT_KEY_REQ".data_bytes"              // 请求字节数

#define APM_REPORT_KEY_RESP                     "response"
#define APM_REPORT_KEY_RESP_CODE                APM_REPORT_KEY_RESP".code"                   // 返回码,数字
#define APM_REPORT_KEY_RESP_CODE_STRING         APM_REPORT_KEY_RESP".code_string"            // 返回码字符串表示
#define APM_REPORT_KEY_RESP_ERR_MSG             APM_REPORT_KEY_RESP".error_message"          // 应用层详细错误信息
#define APM_REPORT_KEY_RESP_START_TIMESTAMP     APM_REPORT_KEY_RESP".start_time"             // 首包时间戳(单位毫秒)
#define APM_REPORT_KEY_RESP_END_TIMESTAMP       APM_REPORT_KEY_RESP".end_time"               // 全部下载完成时间戳(单位毫秒)
#define APM_REPORT_KEY_RESP_SERVER_TIME_US      APM_REPORT_KEY_RESP".server_time_us"         // 服务器运行时间(单位usec)
#define APM_REPORT_KEY_RESP_DOWNLOAD_TIME_US    APM_REPORT_KEY_RESP".download_time_us"       // 下载时间(单位usec)
#define APM_REPORT_KEY_RESP_DATA_BYTES          APM_REPORT_KEY_RESP".data_bytes"             // 响应字节数

#define APM_REPORT_KEY_SUB                      "subscription"
#define APM_REPORT_KEY_NOTIFY                   "notify"
#define APM_REPORT_KEY_PUB                      "publish"

#define APM_REPORT_KEY_UPDATE                   "update"
#define APM_REPORT_KEY_UPDATE_EVENT             APM_REPORT_KEY_UPDATE".event"
#define APM_REPORT_KEY_UPDATE_MSG               APM_REPORT_KEY_UPDATE".message"
#define APM_REPORT_KEY_UPDATE_TIMESTAMP         APM_REPORT_KEY_UPDATE".time"

//update event 事件类型
#define APM_REPORT_UPDATE_CONNECT_FAILED    "CONNECT_FAILED"
#define APM_REPORT_UPDATE_CLIENT_ABORT      "CLIENT_ABORT"
#define APM_REPORT_UPDATE_SERVER_ABORT      "SERVER_RESET"
#define APM_REPORT_UPDATE_REQUEST_CANCELLED "REQUEST_CANCELLED"
#define APM_REPORT_UPDATE_LOGON_REJECT      "LOGIN_REJECT"
#define APM_REPORT_UPDATE_LOGON             "LOGIN"
#define APM_REPORT_UPDATE_LOGOUT            "LOGOUT"

//report 数据最大长度(64k)
#define APM_REPORT_MAX              65536
/* MQ消息数据上报上限 */
#define APM_REPORT_MQ_MAX           APM_REPORT_MAX

#define APM_REPORT_MAGIC_NUMBER     "BROADAAPM"

/*! @brief 上报数据类型 */
typedef enum __em_report_type
{
    FRREPORT_TYPE_UNKNOWN = 0,
    FRREPORT_TYPE_STAT_PORT,        /*!< port 端口统计 */
    FRREPORT_TYPE_STAT_CONN,        /*!< 连接数流量统计 */
    FRREPORT_TYPE_L7DATA,           /*!< l7 请求/响应消息 */
    FRREPORT_TYPE_STAT_L4,          /*!< l4 统计消息 */
}Frreport_type;

/*! @brief 上报数据链表类型 */
typedef enum __em_report_type_list
{
    FRREPORT_TYPE_LIST_COMM,        /*!< comm */
    FRREPORT_TYPE_LIST_REQ,         /*!< request */
    FRREPORT_TYPE_LIST_RESP,        /*!< response */
    FRREPORT_TYPE_LIST_MQ,          /*!< mq相关 */
}Frreport_type_list;

/*! @brief 上报数据体的l7类型 */
typedef enum __em_report_type_l7data
{
    FRREPORT_TYPE_L7DATA_REQ = 0,     /*!< request */
    FRREPORT_TYPE_L7DATA_RESP,        /*!< response */
    FRREPORT_TYPE_L7DATA_PUB,         /*!< pub */
    FRREPORT_TYPE_L7DATA_SUB,         /*!< sub */
    FRREPORT_TYPE_L7DATA_NOTIFY,      /*!< notify */
    FRREPORT_TYPE_L7DATA_UPDATE,      /*!< update event */
    FRREPORT_TYPE_L7DATA_UNKONWN,
}Frreport_type_l7data;

/*! @brief 上报数据头 */
typedef struct __st_report_header {
    char arr_version[2];                /*!< 版本 */
    unsigned long ul_body_len;          /*!< 数据体总长度 */
    char arr_msg_id[APM_UUID_SIZE];
    char arr_agent_from[APM_UUID_SIZE];
    char c_flag_zip;                    /*!< 编码模式  1 – GZIP压缩模式(对数据体进行压缩);0 - 不压缩模式 */
    struct timeval st_event_timestamp;  /*!< 当前数据包生成时间 */
}Frreport_header;

/*! @brief l4统计信息 */
typedef struct __st_report_stat_l4 {
    Frreport_type em_type;
    u_short ip_proto;
    u_int   dst_ip;
    u_short dst_port;

    unsigned long ul_tx_bytes;     //发送流量
    unsigned long ul_rx_bytes;     //接受流量
    unsigned long ul_conns;        //连接数(非累加值)
    unsigned long ul_acks;         //ack数量
    unsigned long ul_resets;       //reset数量
    unsigned long ul_zero_win;     //零窗口数

}Frreport_stat_l4_tcp;

/*! @brief 上报数据体中端口统计信息 */
typedef struct __st_report_stat_port {
    Frreport_type em_type;
    u_short ip_proto;
    u_int   dst_ip;
    u_short dst_port;
    unsigned long ul_tx_bytes;
    unsigned long ul_rx_bytes;
    unsigned long ul_tx_pkts;
    unsigned long ul_rx_pkts;
}Frreport_stat_port;

/*! @brief 上报数据体中连接信息 */
typedef struct __st_report_stat_conn {
    u_int   src_ip;
    u_int   dst_ip;
    u_short dst_port;
    u_int   ui_conns;   /*!< 并发连接数 */
    u_int   ui_refused; /*!< 拒绝连接的次数 */
    u_int   ui_reset;   /*!< 并发连接数 */
    unsigned long ul_tx_bytes;
    unsigned long ul_rx_bytes;
}Frreport_stat_conn;

/*! @brief 上报数据体中l7信息 */
typedef struct __st_report_l7data {
    u_short ip_proto;
    u_int   src_ip;
    u_short src_port;
    u_int   dst_ip;
    u_short dst_port;
    int i_l7_proto;

    Frlist_header   st_hdr_comm;        /*!< 保存session/transaction/connection Frvar_field */
    Frlist_header   st_hdr_req;         /*!< 保存request Frvar_field */
    Frlist_header   st_hdr_resp;        /*!< 保存response Frvar_field */
    Frlist_header   st_hdr_mq;          /*!< 保存mq Frvar_field */
}Frreport_l7data;


/*! @brief 上报数据体部 */
typedef struct __st_report_body_data {
    Frreport_type em_type;
    union
    {
        Frreport_stat_port  st_stat_port;
        Frreport_stat_conn  st_stat_conn;
        Frreport_l7data     st_l7data;
        Frreport_stat_l4_tcp st_stat_l4_tcp;
    } un_data;
}Frreport_body_data;

/*! @brief 上报数据 */
typedef struct __st_report_data {
    Frreport_header st_data_header;

    Frreport_type   em_type;
    Frreport_type_l7data   em_type_l7data;  /*!< l7 data时有效 */
    Frlist_header   st_hdr_body;            /*!< 保存 Frreport_body_data(当em_type==FRREPORT_TYPE_L7DATA时,只有1个节点数据) */
} Frreport_data;

/*! @brief 模块信息 */
typedef struct __st_report_module {
    char *p_module_name;        /*!< 模块名称 */
    char *p_version;            /*!< 版本号 */

    /* 构造函数
     * p_context     框架的上下文引用
     * p_params      so使用参数
     * p_zmq_connect zmq连接信息
     * ; 返回值:成功FR_SUCC, 失败FR_FAIL */
    int (*init)(void *p_context, const char *p_params, const char *p_zmq_connect);
    int (*destroy)(void); /* 析构函数; 返回值:成功FR_SUCC, 失败FR_FAIL */

    /* 加入发送的详细  返回值:成功FR_SUCC, 失败FR_FAIL */
    int (*add_data)(Frreport_data **pp_st_report_data);
    /* 加入发送的连接信息  返回值:成功FR_SUCC, 失败FR_FAIL */
    int (*add_conn)(Conntrack *p_st_ct, int i_status, struct timeval st_timeval);
    /* 不间断把缓存的上报信息发送到客户端 */
    int (*do_task)(int *p_is_run);
    /* 调试开关 */
    int (*debug_switch)(const char *p_debugstr);
    /* 上报模块统计信息  */
    void (*debug_stat)(char *p_outbuff, unsigned int ui_size);
    /* 上报模块统计信息,数据放入json中;  p_st_json (json_object *) */
    void (*debug_stat_json)(void *p_st_json);
} Report_module;

/*!
 * 创建report_data数据结构
 *
 * \param em_type                  (Frreport_type)
 * \param em_type_l7data           (Frreport_type_l7data)
 *
 * \return Frreport_data*; 失败NULL
 *
 */
Frreport_data* __frreport_data_new(Frreport_type em_type, Frreport_type_l7data em_type_l7data);

#define frreport_data_stat_conn_new() __frreport_data_new(FRREPORT_TYPE_STAT_CONN, FRREPORT_TYPE_L7DATA_UNKONWN)
#define frreport_data_stat_port_new() __frreport_data_new(FRREPORT_TYPE_STAT_PORT, FRREPORT_TYPE_L7DATA_UNKONWN)
#define frreport_data_l7_new(em_type_l7data) __frreport_data_new(FRREPORT_TYPE_L7DATA, em_type_l7data)
#define frreport_data_stat_l4_new() __frreport_data_new(FRREPORT_TYPE_STAT_L4, FRREPORT_TYPE_L7DATA_UNKONWN)

/*!
 * 释放report_data数据结构
 *
 * \param pp_st_report_data        (Frreport_data**)
 *
 */
void frreport_data_free(Frreport_data **pp_st_report_data);

/*!
 * 设置report_data的数据体长度
 *
 * \param p_st_report_data     (Frreport_data*)
 * \param ul_body_len          (数据体长度)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int frreport_set_body_len(Frreport_data* p_st_report_data, unsigned long ul_body_len);

/*!
 * 设置report_data的agent_from
 *
 * \param p_st_report_data     (Frreport_data*)
 * \param p_agent_from         (agent的id)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int frreport_set_agent_from(Frreport_data* p_st_report_data, const char *p_agent_from);

/*!
 * 生成Frreport_body_data(tcp信息统计)
 *
 * \param ip_proto      (proto)
 * \param dst_ip        (目的ip)
 * \param dst_port      (目的port)
 * \param ul_tx_bytes   (tx bytes)
 * \param ul_rx_bytes   (rx bytes)
 * \param ul_conns      (连接数)
 * \param ul_acks       (ack数)
 * \param ul_resets     (reset数)
 * \param ul_zero_win   (零窗口数)
 *
 * \return Frreport_body_data*; 失败NULL
 *
 */
Frreport_body_data* frreport_body_new_stat_l4_tcp( u_short ip_proto
                                                   , u_int dst_ip
                                                   , u_short dst_port
                                                   , unsigned long ul_tx_bytes
                                                   , unsigned long ul_rx_bytes
                                                   , unsigned long ul_conns
                                                   , unsigned long ul_acks
                                                   , unsigned long ul_resets
                                                   , unsigned long ul_zero_win);

/*!
 * 生成Frreport_body_data(端口统计)
 *
 * \param ip_proto      (proto)
 * \param dst_ip        (目的ip)
 * \param dst_port      (目的port)
 * \param ul_tx_bytes   (tx bytes)
 * \param ul_rx_bytes   (rx bytes)
 * \param ul_tx_pkts    (tx packets)
 * \param ul_rx_pkts    (rx packets)
 *
 * \return Frreport_body_data*; 失败NULL
 *
 */
Frreport_body_data* frreport_body_new_stat_port( u_short ip_proto
                                               , u_int dst_ip
                                               , u_short dst_port
                                               , unsigned long ul_tx_bytes
                                               , unsigned long ul_rx_bytes
                                               , unsigned long ul_tx_pkts
                                               , unsigned long ul_rx_pkts);

/*!
 * 生成Frreport_body_data(连接数流量统计)
 *
 * \param src_ip        (原ip)
 * \param dst_ip        (目的ip)
 * \param dst_port      (目的port)
 * \param ui_conns      (连接数)
 * \param ui_refused    (拒绝连接数)
 * \param ui_reset      (reset数)
 * \param ul_tx_bytes   (tx bytes)
 * \param ul_rx_bytes   (rx bytes)
 *
 * \return Frreport_body_data*; 失败NULL
 *
 */
Frreport_body_data* frreport_body_new_stat_conn( u_int src_ip
                                               , u_int dst_ip
                                               , u_short dst_port
                                               , u_int   ui_conns
                                               , u_int   ui_refused
                                               , u_int   ui_reset
                                               , unsigned long ul_tx_bytes
                                               , unsigned long ul_rx_bytes);

/*!
 * 生成Frreport_body_data
 *
 * \param p_st_ct                  (Conntrack *)
 *
 * \return Frreport_body_data*; 失败NULL
 *
 */
Frreport_body_data* frreport_body_new_l7(Conntrack *p_st_ct);

/*!
 * 释放Frreport_body_data
 *
 * \param pp_st_body_data                  (Frreport_body_data **)
 *
 */
void frreport_body_free(Frreport_body_data **pp_st_body_data);

/*!
 * 获取l7协议号
 *
 * \param p_st_body_data       (Frreport_body_data *)
 *
 * \return 返回l7 协议号，出错返回 APM_L7_UNKNOWN
 *
 */
int  frreport_body_l7_get_l7module(Frreport_body_data *p_st_body_data);

/*!
 * 设置l7协议号
 *
 * \param p_st_body_data       (Frreport_body_data *)
 * \param i_l7_proto           (l7 协议号)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int  frreport_body_l7_set_l7module(Frreport_body_data *p_st_body_data, int i_l7_proto);

int  frreport_body_l7_add_timeval(Frreport_body_data *p_st_body_data, const char *p_key, struct timeval *p_st_timestamp);
int  frreport_body_l7_add_int(Frreport_body_data *p_st_body_data, const char *p_key, int i_data);
int  frreport_body_l7_add_uint(Frreport_body_data *p_st_body_data, const char *p_key, unsigned int ui_data);
int  frreport_body_l7_add_long(Frreport_body_data *p_st_body_data, const char *p_key, long l_data);
int  frreport_body_l7_add_ulong(Frreport_body_data *p_st_body_data, const char *p_key, unsigned long ul_data);
int  frreport_body_l7_add_float(Frreport_body_data *p_st_body_data, const char *p_key, float f_data);
int  frreport_body_l7_add_double(Frreport_body_data *p_st_body_data, const char *p_key, double d_data);

/*!
 * Frreport_body_data里增加字符串数据(以list形式保存)
 *
 * \param p_st_body_data       (Frreport_body_data *)
 * \param p_key                (const char *)
 * \param p_value              (const char *)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int  frreport_body_l7_add_str(Frreport_body_data *p_st_body_data, const char *p_key, const char *p_value);

/*!
 * Frreport_body_data里增加字符串数据(以list形式保存)
 *
 * \param p_st_body_data       (Frreport_body_data *)
 * \param p_key                (const char *)
 * \param p_value              (const char *)
 * \param ui_limit_value_len   (unsigned int, 如果为0，不限制长度)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int  frreport_body_l7_add_str_limit(Frreport_body_data *p_st_body_data
                                  , const char *p_key, const char *p_value, unsigned int ui_limit_value_len);
#define FRREPORT_BODY_L7_ADD_STR_LIMIT(a, b, c) frreport_body_l7_add_str_limit(a, b, c, APM_REPORT_MQ_MAX)

/*!
 * Frreport_body_data里增加2进制数据(以list形式保存)
 *
 * \param p_st_body_data       (Frreport_body_data *)
 * \param p_key                (const char *)
 * \param p_value              (const char *)
 * \param ui_len               (p_value的数据长度)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int  frreport_body_l7_add_bin(Frreport_body_data *p_st_body_data, const char *p_key, const char *p_value, unsigned int ui_len);

/*!
 * 根据key名，获取对应的list头
 *
 * \param p_st_body_data       (Frreport_body_data *)
 * \param p_key                (const char *)
 *
 * \return Frlist_header *
 *
 */
Frlist_header *frreport_body_l7_get_hdr(Frreport_body_data *p_st_body_data, const char *p_key);

/*!
 * l7data里删除所有相同节点名
 *
 * \param p_st_body_data       (Frreport_body_data *)
 * \param p_key                (const char *)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int  frreport_body_l7_del_all(Frreport_body_data *p_st_body_data, const char *p_key);

/*!
 * l7data里删除指定节点名的第ui_index个
 *
 * \param p_st_body_data       (Frreport_body_data *)
 * \param p_key                (const char *)
 * \param ui_index             (从0开始)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int  frreport_body_l7_del_index(Frreport_body_data *p_st_body_data, const char *p_key, unsigned int ui_index);

/*!
 * Frreport_body_data里追加connection相关信息
 *
 * \param p_st_body_data       (Frreport_body_data *)
 * \param p_st_ct              (Conntrack *)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int  frreport_body_l7_add_connInfo(Frreport_body_data *p_st_body_data, Conntrack *p_st_ct);

/*!
 * Frreport_data里增加体数据(以list形式保存)
 *
 * \param p_st_report_data     (Frreport_data *)
 * \param p_st_body_data       (Frreport_body_data *)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 * \note 返回成功时,外部不用再释放 p_st_body_data
 *
 */
int frreport_data_add_body(Frreport_data *p_st_report_data, Frreport_body_data *p_st_body_data);

/*!
 * 克隆l7 data的list
 *
 * \param p_st_body_data       (Frreport_body_data *)
 * \param em_type_lst          (Frreport_type_list)
 *
 * \return Frreport_body_data *;失败 NULL
 *
 */
Frlist_header* frreport_body_l7list_clone(Frreport_body_data *p_st_body_data, Frreport_type_list em_type_lst);
#define FRREPORT_BODY_L7LIST_CLONE_COMM(x) frreport_body_l7list_clone(x, FRREPORT_TYPE_LIST_COMM)
#define FRREPORT_BODY_L7LIST_CLONE_REQ(x) frreport_body_l7list_clone(x, FRREPORT_TYPE_LIST_REQ)
#define FRREPORT_BODY_L7LIST_CLONE_RESP(x) frreport_body_l7list_clone(x, FRREPORT_TYPE_LIST_RESP)
#define FRREPORT_BODY_L7LIST_CLONE_MQ(x) frreport_body_l7list_clone(x, FRREPORT_TYPE_LIST_MQ)

/*!
 * 设置l7 data的list
 *
 * \param p_st_body_data       (Frreport_body_data *)
 * \param em_type_lst          (Frreport_type_list)
 * \param p_hdr_lst            (Frlist_header*)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int frreport_body_l7list_set(Frreport_body_data *p_st_body_data, Frreport_type_list em_type_lst, Frlist_header **pp_hdr_append);
#define FRREPORT_BODY_L7LIST_SET_COMM(x,y) frreport_body_l7list_set(x, FRREPORT_TYPE_LIST_COMM, y)
#define FRREPORT_BODY_L7LIST_SET_REQ(x,y)  frreport_body_l7list_set(x, FRREPORT_TYPE_LIST_REQ, y)
#define FRREPORT_BODY_L7LIST_SET_RESP(x,y) frreport_body_l7list_set(x, FRREPORT_TYPE_LIST_RESP, y)
#define FRREPORT_BODY_L7LIST_SET_MQ(x,y) frreport_body_l7list_set(x, FRREPORT_TYPE_LIST_MQ, y)

/*!
 * 生成update事件
 *
 * \param p_st_ct           (Conntrack *)
 * \param p_update_eventt   (update event事件)
 * \param p_msg             (时间消息 const char*)
 * \param p_st_timestamp    (事件时间 struct timeval *)
 *
 * \return Frreport_data *
 *
 */
Frreport_data * frreport_update_create(Conntrack *p_st_ct, const char *p_update_eventt, const char *p_msg, struct timeval *p_st_timestamp);

/*!
 * 释放l7 data的list
 *
 * \param pp_hdr            (Frlist_header **)
 *
 * \return Frreport_body_data *;失败 NULL
 *
 */
void frreport_body_l7list_free(Frlist_header **pp_hdr);

/*!
 * Frreport_data数据保存到hash(供协议分析使用)
 *
 * \param p_st_hash_report     (Frhash_header *)
 * \param p_st_report_data     (Frreport_data *)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int frreport_data_hash(Frhash_header *p_st_hash_report, Frreport_data *p_st_report_data);

/*!
 * Frreport_data数据以json格式出力
 *
 * \param p_st_report_data     (Frreport_data *)
 * \param i_flag_style         (FR_YES:格式化输出; FR_NO:无格式化输出)
 *
 * \return json数据, 失败:NULL
 *
 */
char* frreport_data_output(Frreport_data *p_st_report_data, int i_flag_style);

/*!
 * Frreport_data数据发送(保存到发送队列)
 *
 * \param p_frame_ref  (框架引用信息)
 * \param p_st_report_data     (Frreport_data *)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 * \note pp_st_report_data 本函数内部释放
 */
int frreport_send(void* p_frame_ref, Frreport_data **pp_st_report_data);

#endif
